package com.example.testdemo.rxjava_test;

import android.nfc.Tag;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TabHost;
import android.widget.TextView;

import com.example.testdemo.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;


public class RxJavaBtestActivity extends AppCompatActivity {

    public static final String TAG = "RxJavaBtestActivity";
    private Button btnSend;
    private TextView textView;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava_test_a_view);
        initView();
    }

    private void initView() {
        btnSend = findViewById(R.id.button);
        textView = findViewById(R.id.textView2);

        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                testObservable();
//                testObservable2();
                testHttpRequest();
            }
        });
    }


    private void testObservable() {
        Observable
                .create(new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                        Log.i(TAG, "send1");
                        emitter.onNext("哈哈哈哈哈哈哈，幺幺幺幺幺");
                        Log.i(TAG, "send2");
                        emitter.onNext("哈哈哈哈哈哈哈，嘿嘿嘿嘿");
                        Log.i(TAG, "send3");
                        emitter.onNext("哈哈哈哈哈哈哈，哼哼哼哼");
                    }
                })
                .subscribeOn(Schedulers.io())//发射事件得线程
                .observeOn(AndroidSchedulers.mainThread())//订阅线程指定
                .subscribe(new Observer<String>() {

                    // 第二步：初始化Observer
                    private int I;
                    private Disposable mDisposable;

                    @Override
                    public void onNext(String s) {
                        Log.i(TAG, "onNext");
                        textView.setText(s);

                        if (++I == 2) {
                            mDisposable.dispose();
                        }
                    }

                    @Override
                    public void onComplete() {
                        Log.i(TAG, "onComplete");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i(TAG, "onError");
                    }

                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.i(TAG, "onSubscribe");
                        mDisposable = d;
                    }
                });
    }

    /**
     * 测试线程
     */
    private void testObservable2() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
                Log.i(TAG, "Observable thread is " + Thread.currentThread().getName());
                emitter.onNext("哈哈哈哈哈哈哈，幺幺幺幺幺");

            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<String>() {
                    @Override
                    public void accept(String o) throws Exception {
                        Log.i(TAG, "After observeOn(mainThread), Current thread is " + Thread.currentThread().getName());
                        textView.setText(o);
                    }
                })
                .observeOn(Schedulers.io())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String o) throws Exception {
                        Log.i(TAG, "After observeOn(IO), Current thread is " + Thread.currentThread().getName());
                        textView.setText(o);
                    }
                });
    }

    /**
     * Rxjava网络请求模拟
     */
    private void testHttpRequest() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
                Log.i(TAG, "subscribe  thread is "+ Thread.currentThread().getName());
                textView.setText("请求中");
                emitter.onNext(startHttpRequest("https://api.github.com/users/basil2style"));
            }
        })
                .map(new Function<String, InitData>() {
                    @Override
                    public InitData apply(String s) {
                        Log.i(TAG, "map apply 解析中 thread is "+ Thread.currentThread().getName());
                        textView.setText("解析中");
                        return paraseJson(s);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<InitData>() {
                    @Override
                    public void accept(InitData initData) throws Exception {
                        Log.i(TAG, "doOnNext 保存中 thread is "+ Thread.currentThread().getName());
                        textView.setText("保存中");
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<InitData>() {
                    @Override
                    public void accept(InitData initData) throws Exception {
                        Log.i(TAG, "observer onNext thread is "+ Thread.currentThread().getName());
                        textView.setText("id="+initData.id +" name="+initData.name +" type="+initData.type +"url="+initData.url);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.i(TAG, "observer onerror");

                    }
                });
    }

    private String startHttpRequest(String strurl) {
        StringBuffer result = null;
        try {
            URL url = new URL(strurl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            connection.connect();
            int responseCode = connection.getResponseCode();
            if (responseCode == 200) {
                result = new StringBuffer();
                BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
                byte[] b = new byte[1024];
                int len = -1;
                while ((len = bis.read(b)) != -1) {
                    result.append(new String(b, 0, len));
                }
                bis.close();
                bis = null;
            }
            connection.disconnect();
            connection = null;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }


    private InitData paraseJson(String data) {
        //解析
        InitData infoData = new InitData();
        try {
            JSONObject object = new JSONObject(data);
            infoData.id = object.getInt("id");
            infoData.url = object.getString("url");
            infoData.name = object.getString("name");
            infoData.type = object.getString("type");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return infoData;
    }

    public class InitData {
        public int id;
        public String name;
        public String type;
        public String url;
    }
}
